package yxy.apple.util.redisson;

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;

public class RedisConnection {

	private boolean ready = false;

	private RedissonClient client = null;

	public boolean ready() {
		return this.ready;
	}

	/**
	 * 复用已有链接
	 *
	 * @param connection
	 * @throws RedisException
	 */
	public synchronized void reuse(RedisConnection connection) throws RedisException {
		if (connection.ready) {
			if (this.client != null) {
				this.disconnect();
			}
			this.client = connection.client;
			this.ready = true;
		} else {
			throw new RedisException("连接不可用");
		}
	}

	public synchronized boolean connect(String address, String password, int database, boolean forced,
			org.redisson.client.codec.BaseCodec codec) throws RedisException {
		try {
			Config config = new Config();
			{
				SingleServerConfig server = config.useSingleServer();
				server.setAddress(address);
				server.setPassword(password);
				server.setDatabase(database);
				/*
				server.setIdleConnectionTimeout(10000);
				//server.setPingTimeout(1000);
				server.setConnectTimeout(10000);
				server.setTimeout(3000);
				server.setRetryAttempts(3);
				server.setSubscriptionsPerConnection(5);
				server.setSubscriptionConnectionMinimumIdleSize(1);
				server.setSubscriptionConnectionPoolSize(50);
				server.setConnectionMinimumIdleSize(32);
				server.setConnectionPoolSize(64);
				server.setDnsMonitoringInterval(-1);
				//server.setDnsMonitoringInterval(5000);
				 */
			}
			//config.setThreads(0);
			//config.setNettyThreads(0);
			//			config.setCodec(new org.redisson.codec.JsonJacksonCodec());
			config.setCodec(codec);
			//config.setTransportMode(TransportMode.NIO);

			return this.connect(config, forced);
		} catch (Exception e) {
			throw new RedisException(e);
		}
	}

	/**
	 * 使用FastjsonCodec作为默认编码器
	 *
	 * @param address
	 * @param password
	 * @param database
	 * @param forced
	 * @return
	 * @throws RedisException
	 */
	public synchronized boolean connect(String address, String password, int database, boolean forced)
			throws RedisException {
		return this.connect(address, password, database, forced, new FastjsonCodec());
	}

	public synchronized boolean connect(String yaml, boolean forced) throws RedisException {
		try {
			Config config = Config.fromYAML(yaml);
			return this.connect(config, forced);
		} catch (Exception e) {
			throw new RedisException(e);
		}
	}

	public synchronized boolean connect(Config config, boolean forced) throws RedisException {
		try {
			if (this.ready && !forced) {
				return true;
			} else {
				this.disconnect();
				this.client = Redisson.create(config);
				this.ready = true;
				return this.ready;
			}
		} catch (Exception e) {
			throw new RedisException(e);
		}
	}

	public synchronized void disconnect() {
		if (this.client != null && !this.client.isShuttingDown()) {
			this.client.shutdown();
			this.client = null;
		}
		this.ready = false;
	}

	public RedissonClient client() {
		return this.client;
	}

	public RedisConnection setClient(RedissonClient client) {
		this.client = client;
		this.ready = true;
		return this;
	}
}
